今天終於可以來畫迷宮了!嗯...感覺畫出來有點 bug XD
再試試看好了。
edit: 喔喔好像成功了。
程式碼大概長這樣:
#canvas({
import draw:*
let gen-maze(m, n) = {
let dfs-stack = ((0, 0),)
let dfs-ptr = (0,)
let dfs-mark = ()
let dfs-visited = ()
let rng = gen-rng-f(90)
let dir = ((0, -1), (-1, 0), (0, 1), (1, 0))
let pow2=(1, 2, 4, 8)
let ret = ()
let dbg = ()
(rng, dfs-mark) = integers-f(rng, low:0, high:16, size:m * n)
dfs-visited = (..dfs-mark).map((x)=>0).chunks(n)
dfs-mark = dfs-mark.chunks(n)
dfs-visited.at(0).at(0) = 1
for loop_count in range(100000) {
dbg.push((dfs-stack, dfs-ptr))
if dfs-stack.len() == 0 {
break
}
let (x, y) = dfs-stack.last()
if dfs-ptr.last() == 4 {
let t = dfs-mark.at(x).at(y)
let _ = dfs-ptr.pop()
let _ = dfs-stack.pop()
circle((x+0.5, y+0.5), radius: 0.2, fill:blue.lighten(50%), stroke:none)
// content((), [#dfs-stack.len()])
// content((), [#t])
if dfs-stack.len() > 0 {
let (px, py) = dfs-stack.at(dfs-stack.len() - 1)
line((x+0.5, y+0.5), (px+0.5, py+0.5), stroke:blue.lighten(50%)+2pt)
}
if t in (1, 3, 5, 7, 9, 11, 13, 15) {
// ret.push(line((x, y), (x+1, y)))
line((x, y), (x+1, y))
}
if t in (2, 3, 6, 7, 10, 11, 14, 15) {
// ret.push(line((x, y), (x, y+1)))
line((x, y), (x, y+1))
}
if t in (4, 5, 6, 7, 12, 13, 14, 15) {
// ret.push(line((x, y+1), (x+1, y+1)))
line((x, y+1), (x+1, y+1))
}
if t in (8, 9, 10, 11, 12, 13, 14, 15) {
// ret.push(line((x+1, y), (x+1, y+1)))
line((x+1, y), (x+1, y+1))
}
continue
}
let i = dfs-ptr.last()
dfs-ptr.at(dfs-ptr.len() - 1) = i + 1
if dfs-mark.at(x).at(y).bit-and(pow2.at(i)) != 0 {
continue
}
let (nx, ny) = (x + dir.at(i).at(0), y + dir.at(i).at(1))
dbg.push(dfs-ptr)
if nx >= 0 and nx < m and ny >= 0 and ny < n {
if dfs-visited.at(nx).at(ny) == 0 {
dfs-visited.at(nx).at(ny) = 1
dfs-stack.push((nx, ny))
dfs-ptr.push(0)
let j = calc.rem(i + 2, 4)
if dfs-mark.at(nx).at(ny).bit-and(pow2.at(j)) != 0 {
dfs-mark.at(nx).at(ny) = dfs-mark.at(nx).at(ny).bit-xor(pow2.at(j))
}
} else if dfs-stack.len() > 1 and (nx != dfs-stack.at(-2).at(0) or ny != dfs-stack.at(-2).at(1)) {
dfs-mark.at(x).at(y) = dfs-mark.at(x).at(y).bit-or(pow2.at(i))
}
} else {
dfs-mark.at(x).at(y) = dfs-mark.at(x).at(y).bit-or(pow2.at(i))
}
}
}
gen-maze(15, 11)
})